﻿/* Copyright (c) 2015 Slava Naumenko - http://m4w.codeplex.com */

using Microsoft.Office.DocumentManagement.DocumentSets;
using Microsoft.SharePoint;
using System;
using System.Web.Services;

namespace M4W.ASM.Services
{
    [WebService(Namespace = "M4W.ASM.Services")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.Web.Script.Services.ScriptService]
    [System.ComponentModel.ToolboxItem(false)]
    public class Document : System.Web.Services.WebService
    {
        [WebMethod]
        public string GetParentSetId(string Library, string ItemId)
        {
            string result = "";
            try
            {
                result = DocumentGetParentSetId.Invoke(Library, ItemId);
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }

        [WebMethod]
        public string Rename(string Library, string ItemId, string Mode)
        {
            string result = "";
            try
            {
                result = DocumentRename.Invoke(Library, ItemId, Mode);
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }

        [WebMethod]
        public string Move(string Library, string ItemId, string Target)
        {
            string result = "";
            try
            {
                result = DocumentMove.Invoke(Library, ItemId, Target);
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }
    }

    // Invocations

    internal static class DocumentGetParentSetId
    {
        internal static string Invoke(string Library, string ItemId)
        {
            string result = "-1";

            string curl = Helper.GetCurrentUrl();

            using (SPSite site = new SPSite(curl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPDocumentLibrary lib = (SPDocumentLibrary)Helper.GetList(web, Library);
                    if (lib == null)
                    {
                        result = "Library '" + Library + "' not found.";
                    }
                    else
                    {
                        SPListItem doc = lib.GetItemById(Int16.Parse(ItemId));
                        if (doc.File != null)
                        {
                            DocumentSet docSet = DocumentSet.GetDocumentSet(doc.File.ParentFolder);
                            if (docSet.Item != null)
                            {
                                result = docSet.Item.ID.ToString();
                            }
                        }
                    }
                }
            }

            return result;
        }
    }

    internal static class DocumentRename
    {
        internal static string Invoke(string Library, string ItemId, string Mode)
        {
            string result = "";

            HandleEventFiring handleEventFiring = new HandleEventFiring();
            handleEventFiring.DisableHandleEventFiring();

            string curl = Helper.GetCurrentUrl();

            try
            {
                using (SPSite site = new SPSite(curl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        web.AllowUnsafeUpdates = true;

                        SPList lib = Helper.GetList(web, Library);
                        SPListItem doc = lib.GetItemById(Int16.Parse(ItemId));
                        SPFile file = doc.File;
                        string fileName = file.Name;
                        string fileNewName = "";

                        if (Mode.StartsWith("."))
                        {
                            fileNewName = fileName.Substring(0, fileName.LastIndexOf(".")) + Mode;
                            Byte[] fileBytes = file.OpenBinary();

                            SPFileCollection files = lib.RootFolder.Files;
                            SPFile newFile = files.Add(lib.RootFolder.Url + "/" + fileNewName, fileBytes, true);

                            SPListItem docNew = lib.GetItemById(newFile.ListItemAllFields.ID);

                            if (docNew != null)
                            {
                                string f;
                                foreach (SPField field in doc.Fields)
                                {
                                    if (!field.ReadOnlyField)
                                    {
                                        f = field.InternalName;
                                        docNew[f] = doc[f];
                                    }
                                }
                                docNew["Author"] = doc["Author"];
                                docNew["Editor"] = doc["Editor"];
                                docNew.SystemUpdate(false);

                                doc.Delete();
                            }
                        }
                        else
                        {
                            fileNewName = Mode + fileName.Substring(fileName.LastIndexOf("."));

                            doc["Name"] = Mode;
                            doc.SystemUpdate(false);
                        }

                        result = fileNewName;

                        web.AllowUnsafeUpdates = false;
                    }
                }
            }
            catch (Exception ex)
            {
                result = ex.Message;
            }
            finally
            {
                handleEventFiring.EnableHandleEventFiring();
            }

            return result;
        }
    }

    internal static class DocumentMove
    {
        internal static string Invoke(string Library, string ItemId, string Target)
        {
            string result = "";

            HandleEventFiring handleEventFiring = new HandleEventFiring();
            handleEventFiring.DisableHandleEventFiring();

            string curl = Helper.GetCurrentUrl();

            try
            {
                using (SPSite site = new SPSite(curl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        web.AllowUnsafeUpdates = true;

                        SPList lib = Helper.GetList(web, Library);
                        SPListItem doc = lib.GetItemById(Int16.Parse(ItemId));
                        SPFile file = doc.File;
                        string fileName = file.Name;

                        Byte[] fileBytes = file.OpenBinary();

                        SPList libNew = Helper.GetList(web, Target);

                        SPWeb webNew = null;
                        if (libNew.ParentWebUrl != lib.ParentWebUrl)
                        {
                            webNew = site.OpenWeb(libNew.ParentWebUrl);
                            webNew.AllowUnsafeUpdates = true;
                        }

                        SPFileCollection files = libNew.RootFolder.Files;
                        SPFile newFile = files.Add(libNew.RootFolder.Url + "/" + fileName, fileBytes, true);

                        SPListItem docNew = libNew.GetItemById(newFile.ListItemAllFields.ID);

                        if (docNew != null)
                        {
                            string f;
                            foreach (SPField field in doc.Fields)
                            {
                                if (!field.ReadOnlyField)
                                {
                                    f = field.InternalName;
                                    if (Helper.ListFieldExists(libNew, f))
                                    {
                                        docNew[f] = doc[f];
                                    }
                                }
                            }
                            docNew["Author"] = doc["Author"];
                            docNew["Editor"] = doc["Editor"];
                            docNew.SystemUpdate(false);

                            doc.Delete();
                        }

                        if (webNew != null)
                        {
                            webNew.AllowUnsafeUpdates = false;
                            webNew.Dispose();
                        }

                        result = Target + "/" + fileName; result = result.Replace("//", "/");

                        web.AllowUnsafeUpdates = false;
                    }
                }
            }
            catch (Exception ex)
            {
                result = ex.Message;
            }
            finally
            {
                handleEventFiring.EnableHandleEventFiring();
            }

            return result;
        }
    }
}